package com.adee.netty.mydubbo.client;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.util.concurrent.Callable;

public class MyDubboConsumerHandler extends SimpleChannelInboundHandler<String>
                implements Callable<String> {
    private final Object contextLock = new Object();
    private ChannelHandlerContext context;
    private String req; // 格式：类名#方法名#参数，HelloService#hello#i am jack
    private String result;
    private MyDubboConsumer consumer;

    public MyDubboConsumerHandler(MyDubboConsumer c) {
        consumer = c;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        String req = "HelloService#hello#this is Jack";
//        ctx.channel().writeAndFlush(req);
        synchronized (contextLock) {
            System.out.println("设置context");
            context = ctx;
            contextLock.notify();
        }
    }

    @Override
    protected synchronized void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println("channelRead1: " + msg);
        result = msg;
        notify();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    // 外部线程调用
    @Override
    public synchronized String call() throws Exception {
        System.out.println("call...");
        if (context == null) {
            synchronized (contextLock) {
                while (context == null) {
                    contextLock.wait();
                }
            }
        }
        Channel c = context.channel();
        c.writeAndFlush(req);
        wait(); // 外部线程等待请求响应，被channelRead0方法中notify唤醒
        return result;
    }
    // 外部线程调用，把请求协议串设置进来，供call方法使用
    public void setReq(String req) {
        this.req = req;
    }
}
